import { useGameStore } from '@/stores/modules/game'

import type { IChef, IRecipe } from '@/stores/types'

const USE_MATERIAL = ['UseFish', 'UseCreation', 'UseMeat', 'UseVegetable'] as const
const COLLECTING = ['Vegetable', 'Fish', 'Creation', 'Meat'] as const
const USE_TECHNIQUES = [
  'UseKnife',
  'UseSteam',
  'UseBoil',
  'UseBake',
  'UseStirfry',
  'UseFry',
] as const
type Collecting = (typeof COLLECTING)[number]
type UseMaterial = (typeof USE_MATERIAL)[number]
type UseTechniques = (typeof USE_TECHNIQUES)[number]

export type EffectType = Collecting | UseMaterial | UseTechniques

interface IEffect {
  cal: string
  condition: string
  type: EffectType
  value: number
}

function isUseMaterialType(value: EffectType): value is UseMaterial {
  return USE_MATERIAL.includes(value as UseMaterial)
}

function isUseTechniquesType(value: EffectType): value is UseTechniques {
  return USE_TECHNIQUES.includes(value as UseTechniques)
}

/**
 * 厨师使用食物材料来源对菜谱价格的加成
 * @param effect
 * @param recipe
 * @returns
 */
function ruleUseMaterial(effect: IEffect, recipe: IRecipe) {
  let result = 0
  const { materialsMap } = useGameStore()

  const typeMap: Record<UseMaterial, string[]> = {
    UseMeat: ['牧场', '鸡舍', '猪圈'],
    UseFish: ['池塘'],
    UseCreation: ['作坊'],
    UseVegetable: ['森林', '菜地', '菜棚'],
  }

  const { cal, condition, type, value } = effect

  if (isUseMaterialType(type)) {
    const isUseMaterial = recipe.materials.some((s) => {
      const materialInfo = materialsMap.get(s.material)
      if (materialInfo) {
        return typeMap[type].includes(materialInfo.origin)
      }
      return false
    })

    if (isUseMaterial && cal === 'Percent' && condition === 'Self') {
      result = value / 100
    }
  }

  return result
}

/**
 * 厨师技法对菜谱价格的加成
 * @param effect
 * @param recipe
 * @returns
 */
function ruleUseTechniques(effect: IEffect, recipe: IRecipe) {
  let result = 0

  const typeMap = {
    UseKnife: 'knife',
    UseSteam: 'steam',
    UseBoil: 'boil',
    UseBake: 'bake',
    UseStirfry: 'stirfry',
    UseFry: 'fry',
  } as const

  const { cal, condition, type, value } = effect

  if (isUseTechniquesType(type)) {
    const isUseTechniques = recipe[typeMap[type]] > 0
    if (isUseTechniques && cal === 'Percent' && condition === 'Self') {
      result = value / 100
    }
  }

  return result
}

/**
 * 计算厨师技能对菜谱价格的加成
 * @param chef
 * @param recipe
 * @returns
 */
export function calcPriceBonusFromSkill(chef: IChef, recipe: IRecipe) {
  let result = 0
  const { skillsMap } = useGameStore()

  const skill = skillsMap.get(chef.skill)
  if (!skill) return result

  const allBonus: number[] = []
  skill.effect.forEach((f) => {
    let bonus = 0
    if (isUseTechniquesType(f.type)) {
      bonus = ruleUseTechniques(f, recipe)
    } else if (isUseMaterialType(f.type)) {
      bonus = ruleUseMaterial(f, recipe)
    }
    allBonus.push(bonus)
  })

  if (allBonus.length) {
    result = Math.max(...allBonus)
  }

  return result
}
